#ifndef DockOverlayH
#define DockOverlayH
/*******************************************************************************
** Qt Advanced Docking System
** Copyright (C) 2017 Uwe Kindler
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/


//============================================================================
//                                   INCLUDES
//============================================================================
#include <QPointer>
#include <QHash>
#include <QRect>
#include <QFrame>

#include "ads_globals.h"

QT_FORWARD_DECLARE_CLASS(QGridLayout)

namespace ads
{
// 定义私有结构体 DockOverlayPrivate
struct DockOverlayPrivate;

// 定义类 CDockOverlayCross
class CDockOverlayCross;

/*! 
 * DockOverlay 绘制一个半透明的矩形覆盖在另一个小部件上。矩形的几何形状基于鼠标位置。
 */
class ADS_EXPORT CDockOverlay : public QFrame
{
	Q_OBJECT
// CDockOverlay 类的私有成员
private:
    DockOverlayPrivate* d;
    // 友元类和结构体
    friend struct DockOverlayPrivate;
    friend class DockOverlayCross;

// CDockOverlay 类的公有成员
public:
    using Super = QFrame;
    // 枚举类型
    enum eMode
    {
        ModeDockAreaOverlay,
        ModeContainerOverlay
    };
    // 构造函数
    CDockOverlay(QWidget* parent, eMode Mode = ModeDockAreaOverlay);
    // 虚析构函数
    virtual ~CDockOverlay();
    // 配置允许停靠的区域
    void setAllowedAreas(DockWidgetAreas areas);
    // 启用/禁用特定区域
    void setAllowedArea(DockWidgetArea area, bool Enable);
    // 返回所有允许的停靠区域标志
    DockWidgetAreas allowedAreas() const;
    // 返回当前鼠标位置下的停靠区域
    DockWidgetArea dropAreaUnderCursor() const;
    // 如果停靠区域是 CenterDockWidgetArea 或侧边栏区域，则返回鼠标下的选项卡索引。
    // 在调用 dropAreaUnderCursor() 后调用此函数，因为此函数会更新选项卡索引。
    // -1 表示第一个选项卡之前的位置，tabCount() 表示最后一个选项卡之后的位置。
    // -2 表示一个有效值
    int tabIndexUnderCursor() const;

	/**
 * 该函数返回与dropAreaUnderCursor()相同的值，如果该覆盖层未隐藏且启用了拖放预览，则返回InvalidDockWidgetArea；如果该覆盖层隐藏或者未启用拖放预览，则返回InvalidDockWidgetArea。
 */
DockWidgetArea visibleDropAreaUnderCursor() const;

/**
 * 显示给定目标窗口部件的拖放覆盖层
 */
DockWidgetArea showOverlay(QWidget* target);

/**
 * 隐藏覆盖层
 */
void hideOverlay();

/**
 * 启用/禁用半透明覆盖矩形，表示拖放窗口的未来区域
 */
void enableDropPreview(bool Enable);

/**
 * 如果启用了拖放预览，则返回true
 */
bool dropPreviewEnabled() const;

/**
 * 目标区域的拖放覆盖矩形
 */
QRect dropOverlayRect() const;

/**
 * 处理polish事件
 */
virtual bool event(QEvent *e) override;

protected:
virtual void paintEvent(QPaintEvent *e) override;
virtual void showEvent(QShowEvent* e) override;
virtual void hideEvent(QHideEvent* e) override;
};

struct DockOverlayCrossPrivate;

/**
 * DockOverlayCross显示一个带有5个不同拖放区域可能性的十字架。
 * 我本可以将所有内容都处理在DockOverlay内部，但是由于一些样式问题，最好为十字架单独创建一个类。
 * 您可以使用属性系统来设置十字架图标的样式。
 * \code
 * ads--CDockOverlayCross
 * {
 *     qproperty-iconFrameColor: palette(highlight);
 *     qproperty-iconBackgroundColor: palette(base);
 *     qproperty-iconOverlayColor: palette(highlight);
 *     qproperty-iconArrowColor: rgb(227, 227, 227);
 *     qproperty-iconShadowColor: rgb(0, 0, 0);
 * }
 * \endcode
 * 或者，您可以使用iconColors属性以AARRGGBB值的十六进制字符串形式传递值，如下面的示例所示。
 * \code
 * ads--CDockOverlayCross
 * {
 *     qproperty-iconColors: "Frame=#ff3d3d3d Background=#ff929292 Overlay=#1f3d3d3d Arrow=#ffb4b4b4 Shadow=#40474747";
 * }
 * \endcode
 */
class CDockOverlayCross : public QWidget
{
	Q_OBJECT
	Q_PROPERTY(QString iconColors READ iconColors WRITE setIconColors) // 用于设置和获取iconColors属性的宏
	Q_PROPERTY(QColor iconFrameColor READ iconColor WRITE setIconFrameColor) // 用于设置和获取iconFrameColor属性的宏
	Q_PROPERTY(QColor iconBackgroundColor READ iconColor WRITE setIconBackgroundColor) // 用于设置和获取iconBackgroundColor属性的宏
	Q_PROPERTY(QColor iconOverlayColor READ iconColor WRITE setIconOverlayColor) // 用于设置和获取iconOverlayColor属性的宏
	Q_PROPERTY(QColor iconArrowColor READ iconColor WRITE setIconArrowColor) // 用于设置和获取iconArrowColor属性的宏
	Q_PROPERTY(QColor iconShadowColor READ iconColor WRITE setIconShadowColor) // 用于设置和获取iconShadowColor属性的宏
public:
	enum eIconColor
	{
		FrameColor, ///< 小窗口图标的边框颜色
		WindowBackgroundColor, ///< 小窗口图标的背景颜色
		OverlayColor, ///< 图标中显示的覆盖层（停靠位置）的颜色
		ArrowColor, ///< 指向方向的箭头的颜色
		ShadowColor ///< 绘制在图标下方的阴影矩形的颜色
	};
private:
	DockOverlayCrossPrivate* d; // 私有指针d
	friend struct DockOverlayCrossPrivate; // 友元结构体DockOverlayCrossPrivate
	friend class CDockOverlay; // 友元类CDockOverlay
protected:
	/**
	 * 此函数返回一个空字符串，仅用于使moc静默
	 */
	QString iconColors() const;

    /**
 * 这是一个用于属性系统的虚拟函数
 */
QColor iconColor() const {
    return QColor();
}

/**
 * 设置图标边框颜色
 */
void setIconFrameColor(const QColor& Color) {
    setIconColor(FrameColor, Color);
}

/**
 * 设置图标背景颜色
 */
void setIconBackgroundColor(const QColor& Color) {
    setIconColor(WindowBackgroundColor, Color);
}

/**
 * 设置图标覆盖层颜色
 */
void setIconOverlayColor(const QColor& Color) {
    setIconColor(OverlayColor, Color);
}

/**
 * 设置图标箭头颜色
 */
void setIconArrowColor(const QColor& Color) {
    setIconColor(ArrowColor, Color);
}

/**
 * 设置图标阴影颜色
 */
void setIconShadowColor(const QColor& Color) {
    setIconColor(ShadowColor, Color);
}

/**
 * 创建给定叠加层的交叉图标
 */
CDockOverlayCross(CDockOverlay* overlay);

/**
 * 虚拟析构函数
 */
virtual ~CDockOverlayCross();

/**
 * 设置特定图标颜色
 */
void setIconColor(eIconColor ColorIndex, const QColor& Color);

/**
 * 返回由ColorIndex指定的图标颜色
 */
QColor iconColor(eIconColor ColorIndex) const;

/**
 * 根据当前光标位置返回叠加层交叉图标所在的停靠区域
 * 该函数检查鼠标光标是否在任何拖放指示器小部件内，并返回相应的DockWidgetArea。
 */
DockWidgetArea cursorLocation() const;

/**
 * 设置给定叠加层模式的交叉图标
 */
void setupOverlayCross(CDockOverlay::eMode Mode);

	/** 
 * 重新创建覆盖图标。
 */
void updateOverlayIcons();

/** 
 * 重置并更新。
 */
void reset();

/** 
 * 更新当前位置。
 */
void updatePosition();

/** 
 * 用于设置所有图标颜色的字符串。
 * 您可以使用此属性通过CSS样式表对覆盖图标进行样式设置。
 * 颜色通过颜色标识符和十六进制AARRGGBB值设置，如下例所示。
 * \code 
 * ads--CDockOverlayCross
 * {
 *     qproperty-iconColors: "Frame=#ff3d3d3d Background=#ff929292 Overlay=#1f3d3d3d Arrow=#ffb4b4b4 Shadow=#40474747";
 * }
 */
void setIconColors(const QString& Colors);

protected:
	// 在showEvent函数前添加注释
// 覆盖基类的showEvent函数
virtual void showEvent(QShowEvent* e) override;

// 在setAreaWidgets函数前添加注释
// 设置区域小部件的哈希表
// 参数为包含DockWidgetArea和QWidget指针的哈希表
void setAreaWidgets(const QHash<DockWidgetArea, QWidget*>& widgets);
}; // CDockOverlayCross

} // namespace ads
#endif // DockOverlayH
